package com.ruoyi.system.service.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.common.datasource.DynamicDataSource;
import com.ruoyi.system.domain.SysDataset;
import com.ruoyi.system.domain.SysDatasetVersion;
import com.ruoyi.system.domain.SysDatasource;
import com.ruoyi.system.domain.vo.SysDatasetQuery;
import com.ruoyi.system.mapper.SysDatasetMapper;
import com.ruoyi.system.service.ISysDatasetService;
import com.ruoyi.system.service.ISysDatasourceService;

/**
 * 数据集配置Service业务层实现
 * 
 * @author ruoyi
 */
@Service
public class SysDatasetServiceImpl implements ISysDatasetService
{
    private static final Logger log = LoggerFactory.getLogger(SysDatasetServiceImpl.class);

    @Autowired
    private SysDatasetMapper datasetMapper;

    @Autowired
    private ISysDatasourceService datasourceService;

    /**
     * 查询数据集配置
     */
    @Override
    public SysDataset selectDatasetById(Long datasetId)
    {
        return datasetMapper.selectDatasetById(datasetId);
    }

    /**
     * 根据数据集编码查询数据集配置
     */
    @Override
    public SysDataset selectDatasetByCode(String datasetCode)
    {
        return datasetMapper.selectDatasetByCode(datasetCode);
    }

    /**
     * 查询数据集配置列表
     */
    @Override
    public List<SysDataset> selectDatasetList(SysDatasetQuery datasetQuery)
    {
        return datasetMapper.selectDatasetList(datasetQuery);
    }

    /**
     * 查询所有启用的数据集
     */
    @Override
    public List<SysDataset> selectEnabledDataset()
    {
        return datasetMapper.selectEnabledDataset();
    }

    /**
     * 新增数据集配置
     */
    @Transactional
    @Override
    public int insertDataset(SysDataset dataset)
    {
        // 设置初始版本号
        dataset.setVersion("1.0.0");
        
        // 获取数据源信息
        SysDatasource datasource = datasourceService.selectDatasourceById(Long.valueOf(dataset.getDatasourceId()));
        if (datasource == null)
        {
            throw new ServiceException("数据源不存在");
        }
        dataset.setDatasourceCode(datasource.getDatasourceCode());
        dataset.setDatasourceName(datasource.getDatasourceName());
        
        // 测试数据集是否可用
        Map<String, Object> testResult = testDatasetConnection(dataset);
        if (!(boolean) testResult.get("success"))
        {
            throw new ServiceException("数据集测试失败: " + testResult.get("message"));
        }
        
        // 先插入数据集记录获取自增ID
        int result = datasetMapper.insertDataset(dataset);
        
        // 初始化元数据
        updateDatasetMetadata(dataset.getDatasetId());
        
        // 创建初始版本
        SysDatasetVersion version = new SysDatasetVersion();
        version.setDatasetId(dataset.getDatasetId());
        version.setDatasetName(dataset.getDatasetName());
        version.setDatasetCode(dataset.getDatasetCode());
        version.setVersion(dataset.getVersion());
        version.setDatasetDefinition(dataset.getDatasetDefinition());
        version.setMetadata(dataset.getMetadata());
        version.setChangeDescription("初始版本");
        version.setIsCurrent("1");
        datasetMapper.insertDatasetVersion(version);
        
        return result;
    }

    /**
     * 修改数据集配置
     */
    @Transactional
    @Override
    public int updateDataset(SysDataset dataset)
    {
        // 测试数据集是否可用
        Map<String, Object> testResult = testDatasetConnection(dataset);
        if (!(boolean) testResult.get("success"))
        {
            throw new ServiceException("数据集测试失败: " + testResult.get("message"));
        }
        
        // 获取当前数据集信息
        SysDataset oldDataset = selectDatasetById(dataset.getDatasetId());
        
        // 检查数据集是否存在
        if (oldDataset == null)
        {
            throw new ServiceException("数据集不存在，无法更新");
        }
        
        // 如果定义有变化，创建新版本
        if (!StringUtils.equals(oldDataset.getDatasetDefinition(), dataset.getDatasetDefinition()))
        {
            // 更新版本号（简单的递增）
            String version = oldDataset.getVersion();
            if (version == null || !version.contains(".")) {
                // 设置默认版本号
                version = "1.0.0";
            }
            String[] versionParts = version.split("\\.");
            // 确保版本号格式正确
            if (versionParts.length < 3) {
                throw new ServiceException("数据集版本号格式错误，请联系管理员");
            }
            int patchVersion = Integer.parseInt(versionParts[2]) + 1;
            String newVersion = versionParts[0] + "." + versionParts[1] + "." + patchVersion;
            dataset.setVersion(newVersion);
            
            // 保存新版本
            createNewVersion(dataset, "更新数据集定义");
        }
        
        // 更新元数据
        updateDatasetMetadata(dataset.getDatasetId());
        
        return datasetMapper.updateDataset(dataset);
    }

    /**
     * 批量删除数据集配置
     */
    @Transactional
    @Override
    public int deleteDatasetByIds(Long[] datasetIds)
    {
        // 先删除相关版本
        for (Long datasetId : datasetIds)
        {
            List<SysDatasetVersion> versions = datasetMapper.selectDatasetVersionList(datasetId);
            for (SysDatasetVersion version : versions)
            {
                datasetMapper.deleteDatasetVersionById(version.getVersionId());
            }
        }
        
        return datasetMapper.deleteDatasetByIds(datasetIds);
    }

    /**
     * 删除数据集配置信息
     */
    @Transactional
    @Override
    public int deleteDatasetById(Long datasetId)
    {
        // 先删除相关版本
        List<SysDatasetVersion> versions = datasetMapper.selectDatasetVersionList(datasetId);
        for (SysDatasetVersion version : versions)
        {
            datasetMapper.deleteDatasetVersionById(version.getVersionId());
        }
        
        return datasetMapper.deleteDatasetById(datasetId);
    }

    /**
     * 校验数据集编码是否唯一
     */
    @Override
    public String checkDatasetCodeUnique(SysDataset dataset)
    {
        Long datasetId = StringUtils.isNull(dataset.getDatasetId()) ? -1L : dataset.getDatasetId();
        SysDataset info = datasetMapper.checkDatasetCodeUnique(dataset.getDatasetCode());
        if (StringUtils.isNotNull(info) && info.getDatasetId().longValue() != datasetId.longValue())
        {
            return Constants.NOT_UNIQUE;
        }
        return Constants.UNIQUE;
    }

    /**
     * 测试数据集连接/执行
     */
    @Override
    public Map<String, Object> testDatasetConnection(SysDataset dataset)
    {
        Map<String, Object> result = new HashMap<>();
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        
        try
        {
            // 获取数据源
            DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
            DataSource dataSource = dynamicDataSource.getDataSource(dataset.getDatasourceCode());
            
            if (dataSource == null)
            {
                result.put("success", false);
                result.put("message", "数据源连接失败，请检查数据源状态");
                return result;
            }
            
            conn = dataSource.getConnection();
            stmt = conn.createStatement();
            
            String sql = generateQuerySql(dataset);
            // 限制查询数量，避免测试时查询过多数据
            sql = sql + " LIMIT 10";
            
            rs = stmt.executeQuery(sql);
            
            // 获取元数据信息
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            
            // 获取数据源类型
            String datasourceType = getDatasourceType(dataset.getDatasourceCode());
            
            // 构建返回结果
            result.put("success", true);
            result.put("message", "测试成功");
            result.put("columnCount", columnCount);
            
            // 获取列信息，严格按照元数据规则处理
            List<Map<String, Object>> columns = new ArrayList<>();
            
            // 对于表或视图类型的数据集，尝试获取列注释映射
            Map<String, String> columnCommentsMap = new HashMap<>();
            if (("table".equals(dataset.getDatasetType()) || "view".equals(dataset.getDatasetType())) && conn != null) {
                try {
                    // 根据数据源类型获取列注释
                    columnCommentsMap = getColumnComments(conn, dataset, datasourceType);
                } catch (Exception e) {
                    log.warn("获取列注释失败: {}", e.getMessage());
                }
            }
            
            for (int i = 1; i <= columnCount; i++)
            {
                Map<String, Object> column = new HashMap<>();
                
                // 1. name: 列名
                String columnName = metaData.getColumnName(i);
                column.put("name", columnName);
                
                // 2. type: 数据类型
                String columnType = metaData.getColumnTypeName(i);
                column.put("type", columnType);
                
                // 3. displayName: 显示名称
                String displayName = null;
                
                // 优先使用通过特定SQL获取的列注释
                if (columnCommentsMap.containsKey(columnName)) {
                    displayName = columnCommentsMap.get(columnName);
                }
                
                // 如果没有获取到注释，尝试使用getColumnLabel
                if (StringUtils.isBlank(displayName)) {
                    try {
                        String columnLabel = metaData.getColumnLabel(i);
                        if (StringUtils.isNotBlank(columnLabel) && !columnLabel.equalsIgnoreCase(columnName)) {
                            displayName = columnLabel;
                        }
                    } catch (Exception e) {
                        // 忽略异常
                    }
                }
                
                // 如果仍然没有注释，则使用列名
                if (StringUtils.isBlank(displayName)) {
                    displayName = columnName;
                }
                
                column.put("displayName", displayName);
                columns.add(column);
            }
            result.put("columns", columns);
            
            return result;
        }
        catch (Exception e)
        {
            log.error("数据集测试失败: {}", e.getMessage());
            result.put("success", false);
            result.put("message", e.getMessage());
            return result;
        }
        finally
        {
            try
            {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            }
            catch (SQLException e)
            {
                log.error("关闭数据库连接失败", e);
            }
        }
    }
    
    /**
      * 获取数据源类型
      */
     private String getDatasourceType(String datasourceCode) {
         try {
             SysDatasource datasource = datasourceService.selectDatasourceByCode(datasourceCode);
             return datasource != null ? datasource.getDatasourceType() : null;
         } catch (Exception e) {
             log.error("获取数据源类型失败: {}", e.getMessage());
             return null;
         }
     }
    
    /**
     * 根据数据源类型获取列注释
     */
    private Map<String, String> getColumnComments(Connection conn, SysDataset dataset, String datasourceType) throws SQLException {
        Map<String, String> commentsMap = new HashMap<>();
        Statement stmt = null;
        ResultSet rs = null;
        
        try {
            // 根据数据源类型构建查询列注释的SQL
            String sql = buildColumnCommentsSql(dataset, datasourceType);
            if (StringUtils.isBlank(sql)) {
                return commentsMap;
            }
            
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            
            // 根据不同数据库提取列名和注释
            while (rs.next()) {
                String columnName = rs.getString(1);
                String comment = rs.getString(2);
                if (StringUtils.isNotBlank(columnName) && StringUtils.isNotBlank(comment)) {
                    commentsMap.put(columnName, comment);
                }
            }
        } finally {
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
        }
        
        return commentsMap;
    }
    
    /**
      * 构建查询列注释的SQL
      */
     private String buildColumnCommentsSql(SysDataset dataset, String datasourceType) {
         String tableName = dataset.getDatasetDefinition(); // 使用datasetDefinition获取表名或SQL
         if (StringUtils.isBlank(tableName)) {
             return null;
         }
         
         // 根据不同数据库类型构建不同的SQL
         switch (datasourceType) {
             case "mysql":
                 // 尝试从SQL中提取数据库名，或者使用当前数据库
                 String databaseName = extractDatabaseName(dataset.getDatasetDefinition()); // 使用datasetDefinition获取SQL
                 if (StringUtils.isNotBlank(databaseName)) {
                     return "SELECT column_name, column_comment FROM information_schema.columns WHERE table_schema = '" + databaseName + "' AND table_name = '" + tableName + "'";
                 } else {
                     // 如果无法提取数据库名，则使用当前数据库
                     return "SELECT column_name, column_comment FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = '" + tableName + "'";
                 }
             case "oracle":
                 return "SELECT column_name, comments FROM user_col_comments WHERE table_name = UPPER('" + tableName + "')";
             case "sqlserver":
                 return "SELECT c.name AS column_name, ep.value AS column_comment FROM sys.columns c LEFT JOIN sys.extended_properties ep ON c.object_id = ep.major_id AND c.column_id = ep.minor_id WHERE c.object_id = OBJECT_ID('" + tableName + "')";
             case "postgresql":
                 return "SELECT column_name, col_description((SELECT oid FROM pg_class WHERE relname = '" + tableName + "'), ordinal_position) AS column_comment FROM information_schema.columns WHERE table_name = '" + tableName + "'";
             default:
                 // 其他数据库类型，返回null
                 return null;
         }
     }
     
     /**
      * 从SQL语句中提取数据库名（针对MySQL）
      */
     private String extractDatabaseName(String sql) {
         if (StringUtils.isBlank(sql)) {
             return null;
         }
         
         try {
             // 简单的正则表达式来匹配数据库名，例如：database.table 或 `database`.`table` 
              // 注意：这只是一个基本实现，实际情况可能更复杂 
              java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(?:`([^`]+)`|([^`\\s.]+))\\.\\s*(?:`([^`]+)`|([^`\\s.]+))");
             java.util.regex.Matcher matcher = pattern.matcher(sql);
             if (matcher.find()) {
                 // 尝试从匹配组中获取数据库名
                 for (int i = 1; i <= matcher.groupCount(); i += 2) {
                     if (matcher.group(i) != null) {
                         return matcher.group(i);
                     }
                 }
             }
         } catch (Exception e) {
             // 忽略正则表达式解析错误
             log.debug("解析SQL提取数据库名失败: {}", e.getMessage());
         }
         
         return null;
     }

    /**
     * 预览数据集数据
     */
    @Override
    public List<Map<String, Object>> previewDatasetData(Long datasetId, Map<String, Object> params, Integer limit)
    {
        List<Map<String, Object>> resultList = new ArrayList<>();
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        
        try
        {
            SysDataset dataset = selectDatasetById(datasetId);
            if (dataset == null || !"0".equals(dataset.getStatus()))
            {
                throw new ServiceException("数据集不存在或未启用");
            }
            
            // 获取数据源
            DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
            DataSource dataSource = dynamicDataSource.getDataSource(dataset.getDatasourceCode());
            
            if (dataSource == null)
            {
                throw new ServiceException("数据源连接失败，请检查数据源状态");
            }
            
            conn = dataSource.getConnection();
            stmt = conn.createStatement();
            
            String sql = generateQuerySql(dataset);
            // 限制查询数量
            sql = sql + " LIMIT " + (limit != null ? limit : 50);
            
            rs = stmt.executeQuery(sql);
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            
            // 构建结果集
            while (rs.next())
            {
                Map<String, Object> row = new HashMap<>();
                for (int i = 1; i <= columnCount; i++)
                {
                    String columnName = metaData.getColumnName(i);
                    Object value = rs.getObject(i);
                    row.put(columnName, value);
                }
                resultList.add(row);
            }
            
            return resultList;
        }
        catch (Exception e)
        {
            log.error("数据集预览失败: {}", e.getMessage());
            throw new ServiceException("数据集预览失败: " + e.getMessage());
        }
        finally
        {
            try
            {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            }
            catch (SQLException e)
            {
                log.error("关闭数据库连接失败", e);
            }
        }
    }

    /**
     * 执行数据集查询
     */
    @Override
    public Map<String, Object> executeDatasetQuery(Long datasetId, Map<String, Object> params, Integer pageNum, Integer pageSize)
    {
        Map<String, Object> result = new HashMap<>();
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        
        try
        {
            SysDataset dataset = selectDatasetById(datasetId);
            if (dataset == null || !"0".equals(dataset.getStatus()))
            {
                throw new ServiceException("数据集不存在或未启用");
            }
            
            // 获取数据源
            DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
            DataSource dataSource = dynamicDataSource.getDataSource(dataset.getDatasourceCode());
            
            if (dataSource == null)
            {
                throw new ServiceException("数据源连接失败，请检查数据源状态");
            }
            
            conn = dataSource.getConnection();
            stmt = conn.createStatement();
            
            // 构建查询SQL
            String baseSql = generateQuerySql(dataset);
            
            // 查询总数
            String countSql = "SELECT COUNT(*) FROM (" + baseSql + ") t";
            rs = stmt.executeQuery(countSql);
            long total = 0;
            if (rs.next())
            {
                total = rs.getLong(1);
            }
            rs.close();
            
            // 分页查询
            if (pageNum == null) pageNum = 1;
            if (pageSize == null) pageSize = 10;
            int startRow = (pageNum - 1) * pageSize;
            
            String querySql = baseSql + " LIMIT " + startRow + ", " + pageSize;
            rs = stmt.executeQuery(querySql);
            
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            
            List<Map<String, Object>> dataList = new ArrayList<>();
            while (rs.next())
            {
                Map<String, Object> row = new HashMap<>();
                for (int i = 1; i <= columnCount; i++)
                {
                    String columnName = metaData.getColumnName(i);
                    Object value = rs.getObject(i);
                    row.put(columnName, value);
                }
                dataList.add(row);
            }
            
            result.put("total", total);
            result.put("rows", dataList);
            result.put("pageNum", pageNum);
            result.put("pageSize", pageSize);
            
            return result;
        }
        catch (Exception e)
        {
            log.error("数据集查询失败: {}", e.getMessage());
            throw new ServiceException("数据集查询失败: " + e.getMessage());
        }
        finally
        {
            try
            {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            }
            catch (SQLException e)
            {
                log.error("关闭数据库连接失败", e);
            }
        }
    }

    /**
     * 更新数据集元数据
     */
    @Override
    public boolean updateDatasetMetadata(Long datasetId)
    {
        try
        {
            SysDataset dataset = selectDatasetById(datasetId);
            if (dataset == null)
            {
                return false;
            }
            
            Map<String, Object> testResult = testDatasetConnection(dataset);
            if (!(boolean) testResult.get("success"))
            {
                return false;
            }
            
            // 获取列信息并处理为标准格式
            List<Map<String, Object>> originalColumns = (List<Map<String, Object>>) testResult.get("columns");
            List<Map<String, Object>> standardColumns = new ArrayList<>();
            
            if (originalColumns != null) {
                for (Map<String, Object> col : originalColumns) {
                    Map<String, Object> standardCol = new HashMap<>();
                    
                    // 1. name: 列名
                    String columnName = col.get("name") instanceof String ? (String) col.get("name") : null;
                    standardCol.put("name", columnName);
                    
                    // 2. type: 数据类型
                    String columnType = col.get("type") instanceof String ? (String) col.get("type") : null;
                    standardCol.put("type", columnType);
                    
                    // 3. displayName: 显示名称
                    // 根据元数据规则：如果数据来源是表或视图，则取其注释，没有注释则与列名相同
                    String displayName = null;
                    
                    // 先尝试获取testDatasetConnection方法中处理过的displayName
                    if (col.get("displayName") instanceof String) {
                        displayName = (String) col.get("displayName");
                    }
                    
                    // 确保严格遵循元数据规则：如果没有有效的注释或与列名相同，则使用列名作为显示名称
                    if (StringUtils.isBlank(displayName) || (columnName != null && displayName.equalsIgnoreCase(columnName))) {
                        displayName = columnName;
                    }
                    
                    standardCol.put("displayName", displayName);
                    standardColumns.add(standardCol);
                }
            }
            
            // 构建元数据 - 使用fields键名与前端保持一致
            Map<String, Object> metadata = new HashMap<>();
            metadata.put("fields", standardColumns); // 确保使用fields键名
            metadata.put("columnCount", standardColumns.size());
            metadata.put("updateTime", System.currentTimeMillis());
            
            // 刷新数据量
            Long count = refreshDatasetCount(datasetId);
            metadata.put("dataCount", count);
            
            // 更新元数据
            String metadataJson = JSON.toJSONString(metadata);
            datasetMapper.updateDatasetMetadata(datasetId, metadataJson);
            
            // 更新缓存
            dataset.setMetadata(metadataJson);
            dataset.setDataCount(count);
            
            return true;
        }
        catch (Exception e)
        {
            log.error("更新数据集元数据失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 刷新数据集数据量
     */
    @Override
    public Long refreshDatasetCount(Long datasetId)
    {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        
        try
        {
            SysDataset dataset = selectDatasetById(datasetId);
            if (dataset == null)
            {
                return 0L;
            }
            
            // 获取数据源
            DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
            DataSource dataSource = dynamicDataSource.getDataSource(dataset.getDatasourceCode());
            
            conn = dataSource.getConnection();
            stmt = conn.createStatement();
            
            // 构建计数SQL
            String countSql = "SELECT COUNT(*) FROM (" + generateQuerySql(dataset) + ") t";
            rs = stmt.executeQuery(countSql);
            
            long count = 0;
            if (rs.next())
            {
                count = rs.getLong(1);
            }
            
            // 更新数据量
            datasetMapper.updateDatasetCount(datasetId, count);
            
            return count;
        }
        catch (Exception e)
        {
            log.error("刷新数据集数据量失败: {}", e.getMessage());
            return 0L;
        }
        finally
        {
            try
            {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            }
            catch (SQLException e)
            {
                log.error("关闭数据库连接失败", e);
            }
        }
    }

    /**
     * 根据数据源ID查询数据集列表
     */
    @Override
    public List<SysDataset> selectDatasetByDatasourceId(String datasourceId)
    {
        return datasetMapper.selectDatasetByDatasourceId(datasourceId);
    }

    // 版本管理相关方法

    /**
     * 查询数据集版本历史
     */
    @Override
    public List<SysDatasetVersion> selectDatasetVersionList(Long datasetId)
    {
        return datasetMapper.selectDatasetVersionList(datasetId);
    }

    /**
     * 查询指定版本
     */
    @Override
    public SysDatasetVersion selectDatasetVersionById(Long versionId)
    {
        return datasetMapper.selectDatasetVersionById(versionId);
    }

    /**
     * 创建新版本
     */
    @Transactional
    @Override
    public String createNewVersion(SysDataset dataset, String changeDescription)
    {
        // 将所有现有版本标记为非当前版本
        datasetMapper.updateDatasetVersionStatus(dataset.getDatasetId(), "0");
        
        // 创建新版本
        SysDatasetVersion version = new SysDatasetVersion();
        version.setDatasetId(dataset.getDatasetId());
        version.setDatasetName(dataset.getDatasetName());
        version.setDatasetCode(dataset.getDatasetCode());
        version.setVersion(dataset.getVersion());
        version.setDatasetDefinition(dataset.getDatasetDefinition());
        version.setMetadata(dataset.getMetadata());
        version.setChangeDescription(changeDescription);
        version.setIsCurrent("1");
        
        datasetMapper.insertDatasetVersion(version);
        
        return dataset.getVersion();
    }

    /**
     * 回滚到指定版本
     */
    @Transactional
    @Override
    public boolean rollbackToVersion(Long versionId)
    {
        try
        {
            SysDatasetVersion version = selectDatasetVersionById(versionId);
            if (version == null)
            {
                return false;
            }
            
            // 获取数据集信息
            SysDataset dataset = selectDatasetById(version.getDatasetId());
            if (dataset == null)
            {
                return false;
            }
            
            // 更新数据集定义
            dataset.setDatasetDefinition(version.getDatasetDefinition());
            dataset.setMetadata(version.getMetadata());
            
            // 生成新版本号（回滚版本号 + 回滚标记）
            String newVersion = version.getVersion() + ".rollback." + System.currentTimeMillis();
            dataset.setVersion(newVersion);
            
            // 更新数据集
            datasetMapper.updateDataset(dataset);
            
            // 更新版本状态
            datasetMapper.updateDatasetVersionStatus(dataset.getDatasetId(), "0");
            
            // 创建回滚版本记录
            SysDatasetVersion rollbackVersion = new SysDatasetVersion();
            rollbackVersion.setDatasetId(dataset.getDatasetId());
            rollbackVersion.setDatasetName(dataset.getDatasetName());
            rollbackVersion.setDatasetCode(dataset.getDatasetCode());
            rollbackVersion.setVersion(newVersion);
            rollbackVersion.setDatasetDefinition(version.getDatasetDefinition());
            rollbackVersion.setMetadata(version.getMetadata());
            rollbackVersion.setChangeDescription("回滚到版本 " + version.getVersion());
            rollbackVersion.setIsCurrent("1");
            
            datasetMapper.insertDatasetVersion(rollbackVersion);
            
            return true;
        }
        catch (Exception e)
        {
            log.error("回滚版本失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 删除版本
     */
    @Transactional
    @Override
    public int deleteDatasetVersion(Long versionId)
    {
        SysDatasetVersion version = selectDatasetVersionById(versionId);
        if (version == null)
        {
            return 0;
        }
        
        // 不允许删除当前版本
        if ("1".equals(version.getIsCurrent()))
        {
            throw new ServiceException("不能删除当前使用的版本");
        }
        
        return datasetMapper.deleteDatasetVersionById(versionId);
    }

    /**
     * 批量删除版本
     */
    @Transactional
    @Override
    public int deleteDatasetVersionByIds(Long[] versionIds)
    {
        // 检查是否包含当前版本
        for (Long versionId : versionIds)
        {
            SysDatasetVersion version = selectDatasetVersionById(versionId);
            if (version != null && "1".equals(version.getIsCurrent()))
            {
                throw new ServiceException("不能删除当前使用的版本");
            }
        }
        
        return datasetMapper.deleteDatasetVersionByIds(versionIds);
    }

    /**
     * 比较两个版本的差异
     */
    @Override
    public Map<String, Object> compareVersions(Long versionId1, Long versionId2)
    {
        Map<String, Object> result = new HashMap<>();
        
        try
        {
            SysDatasetVersion version1 = selectDatasetVersionById(versionId1);
            SysDatasetVersion version2 = selectDatasetVersionById(versionId2);
            
            if (version1 == null || version2 == null)
            {
                throw new ServiceException("版本不存在");
            }
            
            if (!version1.getDatasetId().equals(version2.getDatasetId()))
            {
                throw new ServiceException("只能比较同一数据集的版本");
            }
            
            result.put("version1", version1);
            result.put("version2", version2);
            
            // 比较数据集定义差异
            boolean definitionChanged = !StringUtils.equals(version1.getDatasetDefinition(), version2.getDatasetDefinition());
            result.put("definitionChanged", definitionChanged);
            
            // 添加定义差异详情
            if (definitionChanged) {
                Map<String, String> definitionDiff = new HashMap<>();
                definitionDiff.put("from", version1.getDatasetDefinition());
                definitionDiff.put("to", version2.getDatasetDefinition());
                result.put("definitionDiff", definitionDiff);
            }
            
            // 比较元数据差异
            boolean metadataChanged = false;
            Map<String, Object> metadataDiff = new HashMap<>();
            
            // 处理元数据可能为null的情况
            String metadata1 = version1.getMetadata();
            String metadata2 = version2.getMetadata();
            
            // 检查元数据是否有变化
            if (!StringUtils.equals(metadata1, metadata2)) {
                metadataChanged = true;
                
                // 详细的元数据比较
                if (StringUtils.isEmpty(metadata1) && StringUtils.isEmpty(metadata2)) {
                    // 两者都为空，不添加差异详情
                } else if (StringUtils.isEmpty(metadata1)) {
                    // 元数据1为空，元数据2不为空
                    metadataDiff.put("type", "added");
                    metadataDiff.put("newValue", metadata2);
                } else if (StringUtils.isEmpty(metadata2)) {
                    // 元数据1不为空，元数据2为空
                    metadataDiff.put("type", "removed");
                    metadataDiff.put("oldValue", metadata1);
                } else {
                    // 两者都不为空，尝试解析为JSON进行比较
                    try {
                        // 尝试将元数据解析为JSON对象，进行结构化比较
                        com.alibaba.fastjson2.JSONObject json1 = com.alibaba.fastjson2.JSONObject.parseObject(metadata1);
                        com.alibaba.fastjson2.JSONObject json2 = com.alibaba.fastjson2.JSONObject.parseObject(metadata2);
                        
                        Map<String, Object> changedFields = compareJsonObjects(json1, json2);
                        if (!changedFields.isEmpty()) {
                            metadataDiff.put("type", "changed");
                            metadataDiff.put("fields", changedFields);
                        }
                    } catch (Exception e) {
                        // 如果解析失败，进行文本比较
                        metadataDiff.put("type", "text_changed");
                        metadataDiff.put("from", metadata1);
                        metadataDiff.put("to", metadata2);
                    }
                }
            }
            
            result.put("metadataChanged", metadataChanged);
            if (metadataChanged && !metadataDiff.isEmpty()) {
                result.put("metadataDiff", metadataDiff);
            }
            
            return result;
        }
        catch (Exception e)
        {
            log.error("比较版本差异失败: {}", e.getMessage());
            throw new ServiceException("比较版本差异失败: " + e.getMessage());
        }
    }
    
    /**
     * 比较两个JSON对象，找出字段级别的差异
     * @param json1 源JSON对象
     * @param json2 目标JSON对象
     * @return 字段变化的详细信息
     */
    private Map<String, Object> compareJsonObjects(com.alibaba.fastjson2.JSONObject json1, com.alibaba.fastjson2.JSONObject json2) {
        Map<String, Object> changedFields = new HashMap<>();
        
        // 检查json1中的字段
        for (String key : json1.keySet()) {
            if (!json2.containsKey(key)) {
                // 字段被删除
                Map<String, Object> changeInfo = new HashMap<>();
                changeInfo.put("type", "removed");
                changeInfo.put("oldValue", json1.get(key));
                changedFields.put(key, changeInfo);
            } else {
                // 字段存在，比较值
                Object value1 = json1.get(key);
                Object value2 = json2.get(key);
                
                if (!StringUtils.equals(String.valueOf(value1), String.valueOf(value2))) {
                    Map<String, Object> changeInfo = new HashMap<>();
                    changeInfo.put("type", "modified");
                    changeInfo.put("oldValue", value1);
                    changeInfo.put("newValue", value2);
                    changedFields.put(key, changeInfo);
                }
            }
        }
        
        // 检查json2中新增的字段
        for (String key : json2.keySet()) {
            if (!json1.containsKey(key)) {
                Map<String, Object> changeInfo = new HashMap<>();
                changeInfo.put("type", "added");
                changeInfo.put("newValue", json2.get(key));
                changedFields.put(key, changeInfo);
            }
        }
        
        return changedFields;
    }

    /**
     * 根据数据集类型生成查询SQL
     */
    private String generateQuerySql(SysDataset dataset)
    {
        String datasetType = dataset.getDatasetType();
        String definition = dataset.getDatasetDefinition();
        
        switch (datasetType)
        {
            case "table":
            case "view":
                return "SELECT * FROM " + definition;
            case "query":
                // 直接返回SQL语句，但需要确保是SELECT语句
                if (!definition.trim().toUpperCase().startsWith("SELECT"))
                {
                    throw new ServiceException("SQL查询语句必须以SELECT开头");
                }
                return definition;
            default:
                throw new ServiceException("不支持的数据集类型: " + datasetType);
        }
    }
}